﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ITAP.ShprossesBuilder.Editor;
using System.Drawing;
using ITAP.ShprossesBuilder.Modelling.Components;
using ITAP.ShprossesBuilder.Modelling.Comparers;
using ITAP.ShprossesBuilder.Modelling;
using ITAP.ShprossesBuilder.Properties;
using ITAP.Core.Modelling;

namespace ITAP.ShprossesBuilder.Operations
{
    public class OperationAlignShprossesEndsRelativeToModelVertical : IOperation
    {
        private ModelControl modelControl;
        #region IOperation Members

        public string Name
        {
            get { return "Вертикальное выравнивание концов профилей по модели"; }
        }

        public OperationGroup OperationGroup
        {
            get { return OperationGroup.ShprossOperation; }
        }

        public System.Drawing.Image Thumbnail
        {
            get { return null; }
        }

        public void Execute(ModelControl modelControl)
        {
            this.modelControl = modelControl;
            ContextMenuStrip menuStrip = new ContextMenuStrip();

            EventHandler handler = new EventHandler(OnItemClick);
            ToolStripItem inner = new ToolStripMenuItem("По внутренним размерам модели", null, handler);
            inner.Tag = AlignRelative.ToInnerModelSize;
            menuStrip.Items.Add(inner);
            ToolStripItem outer = new ToolStripMenuItem("По внешним размерам модели", null, handler);
            outer.Tag = AlignRelative.ToModelSize;
            menuStrip.Items.Add(outer);
            ToolStripItem cell = new ToolStripMenuItem("По размерам ячейки", null, handler);
            cell.Tag = AlignRelative.ToModelCellSize;
            menuStrip.Items.Add(cell);
            ToolStripItem bounds = new ToolStripMenuItem("По крайним концам", null, handler);
            bounds.Tag = AlignRelative.ToBounds;
            menuStrip.Items.Add(bounds);

            menuStrip.Show(Cursor.Position);

        }

        public bool CanUndo
        {
            get { return true; }
        }

        #endregion

        private void OnItemClick(object sender, EventArgs e)
        {
            bool indent = true;
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            AlignRelative align = (AlignRelative)item.Tag;

            RectangleF boundingBox = new RectangleF();

            List<Shpross> shprosses = new List<Shpross>();
            Shpross firstSelectedShpross = null;
            foreach (IComponent selectedComponent in this.modelControl.ModelContainer.SelectedComponentsStack)
                if (selectedComponent is Shpross)
                    shprosses.Add(selectedComponent as Shpross);

            shprosses = shprosses.RemoveDeselectedShprosses();
            if (shprosses.Count == 0)
                return;

            firstSelectedShpross = shprosses[0];

            //shprosses.Sort(new ShprossSelectedEndPointXAxisComparer());

            switch (align)
            {
                case AlignRelative.ToModelSize:
                    boundingBox = ((ModelCell)modelControl.ModelContainer.ActiveCell).Model.BoundingBox;
                    break;
                case AlignRelative.ToInnerModelSize:
                    Model model = ((ModelCell)modelControl.ModelContainer.ActiveCell).Model;
                    boundingBox = model.BoundingBox;
                    boundingBox = new RectangleF(boundingBox.X + (float)model.SpacerWidth, boundingBox.Y + (float)model.SpacerWidth, boundingBox.Width - 2 * (float)model.SpacerWidth, boundingBox.Height - 2 * (float)model.SpacerWidth);
                    break;
                case AlignRelative.ToModelCellSize:
                    boundingBox = ((ModelCell)modelControl.ModelContainer.ActiveCell).BoundingBox;
                    break;
                case AlignRelative.ToBounds:
                    indent = false;
                    shprosses.Sort(new ShprossSelectedEndPointYAxisComparer());
                    boundingBox = new RectangleF((float)firstSelectedShpross.SelectedPointPosition.X, (float)shprosses[0].SelectedPointPosition.Y,
                               0, (float)(shprosses[shprosses.Count - 1].SelectedPointPosition.Y - shprosses[0].SelectedPointPosition.Y));
                    break;
            }

            this.Align(firstSelectedShpross, shprosses, boundingBox, indent);
            this.modelControl.UpdateModel();
        }

        private void Align(Shpross firstSelectedShpross, List<Shpross> shprosses, RectangleF boundingBox, bool indent)
        {
            double offset;
            double x;
            double y;

            if(indent)
                offset = boundingBox.Height / (shprosses.Count + 1);
            else
                offset = boundingBox.Height / (shprosses.Count - 1);
            x = firstSelectedShpross.SelectedPointPosition.X;
            y = boundingBox.Y;
            for (int i = 0; i < shprosses.Count; i++)
            {
                //if (indent)
                //{
                //    y += offset;
                //    if (shprosses[i].SelectedPoint == ShprossPoints.Start)
                //        shprosses[i].MoveStartPointTo(new ModelPoint(x, y));
                //    else if (shprosses[i].SelectedPoint == ShprossPoints.End)
                //        shprosses[i].MoveEndPointTo(new ModelPoint(x, y));
                //    else if (shprosses[i].SelectedPoint == ShprossPoints.Center)
                //        shprosses[i].MoveTo(new ModelPoint(x, y));
                //}
                //else
                //{
                //    if (shprosses[i].SelectedPoint == ShprossPoints.Start)
                //        shprosses[i].MoveStartPointTo(new ModelPoint(x, y));
                //    else if (shprosses[i].SelectedPoint == ShprossPoints.End)
                //        shprosses[i].MoveEndPointTo(new ModelPoint(x, y));
                //    else if (shprosses[i].SelectedPoint == ShprossPoints.Center)
                //        shprosses[i].MoveTo(new ModelPoint(x, y));
                //    y += offset;
                //}
                if (indent)
                {
                    y += offset;
                    if (shprosses[i].SelectedPoint == ShprossPoints.Start)
                        shprosses[i].MoveStartPointTo(new ModelPoint(shprosses[i].StartPoint.X, y));
                    else if (shprosses[i].SelectedPoint == ShprossPoints.End)
                        shprosses[i].MoveEndPointTo(new ModelPoint(shprosses[i].EndPoint.X, y));
                    else if (shprosses[i].SelectedPoint == ShprossPoints.Center)
                        shprosses[i].MoveTo(new ModelPoint(shprosses[i].Position.X, y));
                }
                else
                {
                    if (shprosses[i].SelectedPoint == ShprossPoints.Start)
                        shprosses[i].MoveStartPointTo(new ModelPoint(shprosses[i].StartPoint.X, y));
                    else if (shprosses[i].SelectedPoint == ShprossPoints.End)
                        shprosses[i].MoveEndPointTo(new ModelPoint(shprosses[i].EndPoint.X, y));
                    else if (shprosses[i].SelectedPoint == ShprossPoints.Center)
                        shprosses[i].MoveTo(new ModelPoint(shprosses[i].Position.X, y));
                    y += offset;
                }
            }
        }
    }
}
